package sk.ygor.xtemplate

import collection.mutable.ListBuffer

abstract class ScalaXTemplate {
  def parameter[T] = new TemplateVariable[T]

  val rootBlock: ParsableBlock

  class TemplateVariable[T] {
    var value: T = _
  }

  trait Block {
    def getText: String

    def ~(other: Block): ParsableBlock
  }

  case class ParsableBlock(blocks: List[Block]) extends Block {
    val buffer = new StringBuilder

    private def clear = buffer setLength 0

    def getText = buffer.toString

    def parse = for (block <- blocks) {
      buffer append block.getText
      if (block.isInstanceOf[ParsableBlock]) {
        block.asInstanceOf[ParsableBlock].clear
      }
    }

    def ~(other: Block) = ParsableBlock((new ListBuffer[Block]() ++ blocks + other).toList)

  }

  case class TextBlock(text: String) extends Block {
    def getText = text

    def ~(other: Block) = ParsableBlock(List(this, other))

  }

  case class VariableBlock[T](variable: TemplateVariable[T]) extends Block {
    def getText = if (variable.value == null) "*null*" else variable.value.toString

    def ~(other: Block) = ParsableBlock(List(this, other))
  }

  implicit def stringToTextBlock(s: String): TextBlock = TextBlock(s)

  implicit def variableToBlock[T](v: TemplateVariable[T]) = VariableBlock(v)

}

